package lastfm
{
  import flash.events.EventDispatcher;
  import flash.events.TimerEvent;
  import flash.net.navigateToURL;
  import flash.net.URLRequest;
  import flash.utils.Timer;
  import lastfm.events.ApiEvent;
  import PrivateVars.lastfm;
  import Tools.MD5;

  /**
   * ...
   * @author ...
   */
  public class Auth extends EventDispatcher
  {
    static public var _sessionKey:String = "";
    static public var _token:String = "";
    static private var _tryCount:int = 0;
    static private const _timeout:int = 5000;

    public function Auth()
    {

    }

    static public function clearSession():void
    {
      _sessionKey = "";
    }

    public function authenticateMobileApp(username:String, passwdmd5:String):void
    {
      trace("Auth.authenticateMobileApp: " + username + ", " + passwdmd5);
      var authToken:String = MD5.hash(username.toLowerCase() + passwdmd5);
      var api:Api = new Api;
      api.addEventListener(ApiEvent.OK, onOkGetSession);
      api.addEventListener(ApiEvent.ERROR, onError);
      api.authGetMobileSession(username, authToken);
    }

    public function authenticateDesktopApp():void
    {
      trace("Auth.authenticateDesktopApp ");
      // Step 2. Fetch a request token
      var api:Api = new Api;
      api.addEventListener(ApiEvent.OK, onOkGetToken);
      api.addEventListener(ApiEvent.ERROR, onError);
      api.authGetToken();
    }

    private function onError(e:ApiEvent):void
    {
      trace("Auth.onError: ");
      var ee:ApiEvent = new ApiEvent(ApiEvent.ERROR);
      ee.error = e.error;
      dispatchEvent(ee);
    }

    private function onOkGetSession(e:ApiEvent):void
    {
      trace("Auth.onOkGetSession: key=" + e.response["key"]);
      _sessionKey = e.response["key"];
      var ee:ApiEvent = new ApiEvent(ApiEvent.OK);
      ee.response = e.response;
      dispatchEvent(ee);
    }

    private function onOkGetToken(e:ApiEvent):void
    {
      trace("Auth.onOkGetToken: token=" + e.response["token"]);
      _token = e.response["token"];

      // Step 3. Request authorization from the user
      var url:String = "http://www.last.fm/api/auth/?token=" + _token + "&api_key=" + PrivateVars.lastfm.API_KEY;
      navigateToURL(new URLRequest(url), "_blank");

      // Wait for token authorization for 5 min
      _tryCount = 5 * 60 * 1000 / _timeout; // 5 min
      onTokenTimer(null);
    }

    private function onErrorGetSession(e:ApiEvent):void
    {
      trace("Auth.onErrorGetSession");
      if (14 == e.error.code && 0 < --_tryCount)
      {
        // the token is not authorized, wait...
        var timer: Timer = new Timer(_timeout, 1);
        timer.addEventListener(TimerEvent.TIMER, onTokenTimer);
        timer.start();
      }
      else
      {
        // Unknown error
        var ee:ApiEvent = new ApiEvent(ApiEvent.ERROR);
        ee.error = e.error;
        dispatchEvent(ee);
      }
    }

    private function onTokenTimer(e:TimerEvent):void
    {
      trace("Auth.onTokenTimer");
      // Step 4. Fetch A Web Service Session
      var api:Api = new Api;
      api.addEventListener(ApiEvent.OK, onOkGetSession);
      api.addEventListener(ApiEvent.ERROR, onErrorGetSession);
      api.authGetSession(_token);
    }

    public function get sessionKey():String
    {
      return _sessionKey;
    }

    public function set sessionKey(sk:String):void
    {
      _sessionKey = sk;
    }
  }


}